import React, { useEffect, useState, useRef, useMemo } from 'react';
import ReactDOM from 'react-dom';

// 子组件
const ChildrenComponent = (text, number) => {
    console.log("ChildrenComponent:", text, number)
    return <div>hello,world</div>
}
//子函数
const childrenFunc = (text, number) => {
    console.log("childrenFunc:", text, number)
}

// 子组件
const ChildrenComponent2 = (text, number) => {
    const [number2, setNumber3] = useState(0)
    console.log("ChildrenComponent2:", text, number, number2)
    return <div>hello,world</div>
}

// 使用useMemo优化子组件的渲染
function Index() {
    const [list] = useState([{ id: 1, name: 'xixi' }, { id: 2, name: 'haha' }, { id: 3, name: 'heihei' }])
    const [number, setNumber] = useState(0)
    const [number2, setNumber2] = useState(0)
    const testFunc = () => {
        console.log("testFunc")
    }
    { useMemo(() => childrenFunc(number, number2), [number2, number2]) } //放在这里也一样能起到缓存的作用

    return <div>
        <span>{number}</span>
        <button onClick={() => setNumber(number + 1)} >点击</button>
        <button onClick={() => setNumber2(number + 1)} >点击</button>
        <ul>
            {
                useMemo(() => (list.map(item => {
                    console.log("独立渲染空间") // 可以看出整体组件其他部分变化时,这里并不会重新渲染,形成了独立的渲染空间
                    return <li key={item.id}  >{item.name}</li>
                })), [list])
            }
        </ul>
        {/* 未优化的情况下,每次Index组件重新渲染都会带着子组件一起 */}
        <ChildrenComponent text='no useMemo' number={number}></ChildrenComponent>
        {/* 依赖数组并不会传递给子渲染函数 */}
        {useMemo(() => <ChildrenComponent text='useMemo' number={number} />, ['随便的依赖字段', number2])}
        {useMemo(() => <ChildrenComponent2 text='useMemo' number={number} />, ['随便的依赖字段', number2])}
        {/* 将每次渲染都会比变的组件内定义的函数作为参数传递,也是会变更子组件的,大概是因为函数不是不变的变量 */}
        {/* {useMemo(() => <ChildrenComponent text='useMemo with testFunc' number={number} />, ['随便的依赖字段', testFunc])} */}
        {/* 也可以做函数的优化,一般使用useEffect */}
        {useMemo(() => childrenFunc(number, number2), [number2, number2])}
    </div>
}

const FatherComponment = () => {
    const [number, setNumber] = useState(0)

    return (
        <div>
            <span>{number}</span>
            {/* 根据现象可以看出,父组件重新渲染时子组件也会跟着渲染,但子组件中使用了useMemo的并未重新计数和渲染 */}
            <button onClick={() => setNumber(number + 1)} >验证父组件变化时内部的子组件是否会重新加载点击</button>
            <Index />
        </div>
    )
}


export default FatherComponment